// 封装验证手机号码正则
export function checkMobile(element: string) {
    return (/^1[3|4|5|6|7|8|9][0-9]\d{4,8}$/.test(element))
}

// 生成哈希值
export function createHash(hashLength = 10, ownNumber = true) {
    if (!hashLength || typeof (Number(hashLength)) != 'number') { return; }
    let arr = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z']
    if (ownNumber) {
        arr = [...arr, ...['0', '1', '2', '3', '4', '5', '6', '7', '8', '9']]
    }
    const hs: String[] = []
    for (let index = 0; index < hashLength; index++) {
        hs.push(arr[Math.floor(Math.random() * arr.length)])
    }
    return hs.join('')
}

// 处理微信回调问题
export const promisify = (original: Function, opt = {}): Promise<any> => {
    return new Promise((resolve, reject) => {
        original({
            ...opt,
            success: resolve,
            fail: reject
        })
    })
}

interface objByAnyProp {
    [prop: string]: any;
}

// 跳转到某页面
export const enter = ({
    original = wx.navigateTo, // 调用的微信跳转方法
    query = {}, // 页面路径中的参数
    url = '', // 需要跳转的页面路径
	pageName,
    success,
    fail,
    complete,
    events = {}, // wx.navigateTo方法带有的参数
}: {
    original?: Function,
    query?: objByAnyProp,
    url?: String,
	pageName?: string;
    success?: Function,
    fail?: Function,
    complete?: Function,
    events?: Object,
}) => {
    const queryStr = Object.keys(query).reduce((strArr, key) => {
        if (query[key]) strArr.push(`${key}=${query[key]}`)
        return strArr
    }, [] as string[]).join('&');
	let urlStr = url;
	if (!urlStr && pageName) {
		urlStr = `/pages/${pageName}/${pageName}`;
	}
    original({
        url: `${urlStr}${queryStr ? '?' : ''}${queryStr}`,
        success,
        fail,
        complete,
        events,
    })
}

// 获取小程序当前页面路径
export const getFirstStartPageUrl = (isThisPage = false): Promise<any> => {
    return new Promise(resolve => {
        const page = getCurrentPages()
        if (Array.isArray(page) && page.length > 0) {
            if (isThisPage) {
                resolve(page[0])
                return
            }
            resolve(page)
        } else {
            let count = 0
            const setIntervalId = setInterval(() => {
                if (count > 100) {
                    resolve('')
                    clearInterval(setIntervalId)
                }
                const page = getCurrentPages()
                if (Array.isArray(page) && page.length > 0) {
                    if (isThisPage) {
                        resolve(page[0])
                        return
                    }
                    resolve(page)
                }
                count++
            }, 10)
        }
    })
}

// 根据'pages/pageName/pageName'，返回'pageName'
export const getPageName = (url = '') => {
    if (url) {
        return url.split('/')[2] || ''
    }
    return ''
}

export interface anyObj {
    [propName: string]: any
}

export const wxToast = (
    { icon = 'none', title = '', duration = 2000, complete, success, fail }:
        { icon?: "none" | "success" | "error" | "loading", title: string, duration?: number, complete?: Function, success?: Function, fail?: Function, }
) => {
    const extand: anyObj = {}
    if (complete) {
        extand.complete = complete
    }
    if (success) {
        extand.success = success
    }
    if (fail) {
        extand.fail = fail
    }
    wx.showToast({
        icon,
        title,
        duration,
        ...extand
    })
}

export const wxBack = async ({ delta = 1, defaultPage = '../../pages/index/index' }: { delta?: number, defaultPage?: string }) => {
    const pages = await getFirstStartPageUrl()
    // console.log('pages: ', pages)
    if (pages.length > 1) {
        if (delta > pages.length) delta = pages.length
        wx.navigateBack({
            delta
        })
    } else {
        enter({
            original: wx.redirectTo,
            url: defaultPage
        })
    }
}

/**
 * @desc 函数防抖
 * @param func 函数
 * @param wait 多少秒内执行一次
 * @param immediate true 表立即执行，false 表非立即执行
 * @param context 传this
 */
export function debounce(
    { func, wait = 1000, immediate = true, context }:
        { func: Function, wait?: number, immediate?: Boolean, context: any }
) {
    // console.log('debounce')
    let timeout: any = 0
    return function () {
        const args = [...arguments]
        if (timeout) clearTimeout(timeout)
        if (immediate) {
            const callNow = !timeout
            timeout = setTimeout(() => {
                timeout = null
            }, wait)
            if (callNow) func.apply(context, args)
        } else {
            timeout = setTimeout(() => {
                func.apply(context, args)
            }, wait)
        }
    }
}

export const wxCheckMobile = (mobile: string, name = '联系电话'): Boolean => {
    if (!mobile) {
        wxToast({ title: `请填写${name}` })
        return false
    }
    if (checkMobile(mobile)) {
        return true
    } else {
        wxToast({ title: `请填写正确的${name}` })
    }
    return false
}

// 获取组件实例
export const getComponent = (
    { _this, setKey, id }:
        { _this: any, setKey: string, id: string }
): Promise<any> => {
    return new Promise(resolve => {
        if (_this.data[setKey]) {
            resolve(_this.data[setKey])
        } else {
            let count = 1
            const setIntervalId = setInterval(() => {
                if (count > 1000) {
                    clearInterval(setIntervalId)
                    resolve(false)
                    return
                }
                if (_this.selectComponent(`#${id}`)) {
                    _this.setData({
                        [setKey]: _this.selectComponent(`#${id}`)
                    })
                    clearInterval(setIntervalId)
                    resolve(_this.data[setKey])
                }
                count++
            }, 10)
        }
    })
}

// 预览文档
export const previewDocument = ({ url = '' }) => {
    wx.downloadFile({
        url,
        success: function (res) {
            const filePath = res.tempFilePath;
            console.log('url: ', url);
            console.log('res: ', res);
            if (/(.doc|.docx|.xls|.xlsx|.ppt|.pptx|.pdf)$/.test(url) || /(.doc|.docx|.xls|.xlsx|.ppt|.pptx|.pdf)$/.test(filePath)) {
                wx.openDocument({
                    filePath: filePath,
                    success: function (successRes: any) {
                        console.log("openDocument success res: ", successRes);
                        // console.log('打开文档成功')
                    },
                    fail: function (failRes) {
                        console.log("openDocument fail res: ", failRes)
                        wxEnterWeView({
                            url
                        })
                    }
                })
            } else {
                wxEnterWeView({
                    url
                })
            }
        },
        fail: function (failRes) {
            console.log('failRes: ', failRes);
            wxEnterWeView({
                url
            })
        }
    })
}

// 验证是否为图片链接
export function isImgLink(link = '') {
    return /(.png|.jpeg|.jpg|.gif|.svg|.bmp|.tif|.pcx|.webp|.apng)$/.test(link);
}

// 预览文件
export const previewFile = ({ url = '' }) => {
    if (url) {
        if (isImgLink(url)) {
            wx.previewImage({
                urls: [url],
                current: url
            });
        } else {
            previewDocument({ url });
        }
    }
}

export const getCurrentPageName = async () => {
    const page: any = await getFirstStartPageUrl(true); // 获取当前页面信息
    // console.log('page: ', page)
    return getPageName(page.route); // 获取当前页面名称
};

export const showCloseModal = (title = '认证失败', content = '很抱歉，您不适合我们的工作。祝您生活愉快') => {
    wx.showModal({
        title,
        content,
        confirmText: '确定',
        showCancel: false,
        complete: () => wx.exitMiniProgram()
    });
};

export const toastComplate = (
    {title = "", content = "", confirmText = "确定"}
    : 
    {title: string; content: string; confirmText?: string}
) => {
    return new Promise(resolve => {
        wx.showModal({
            title,
            content,
            confirmText,
            showCancel: false,
            complete: resolve
        });
    });
};

export const showCompleteModal = (
    {title = '提示', content, confirmText = '确定', pageName}
    : 
    {title?: string; content: string; confirmText?: string; pageName: string}
) => {
    wx.showModal({
        title,
        content,
        confirmText,
        showCancel: false,
        complete: () => {
            enter({
                url: `/pages/${pageName}/${pageName}`,
                original: wx.reLaunch
            });
        }
    });
}

export const secondToMinute = (second = 0) => {
	const minute = Math.floor(second / 60);
	const restSeconds = second % 60;
	return minute.toString().padStart(2, '0') + ":" + restSeconds.toString().padStart(2, '0');
}

export const showConfirm = ({title = '提示', content = '', confirmText = '确定', cancelText = '取消'}) => {
    return new Promise((resolve, reject) => {
        wx.showModal({
            title,
            content,
            confirmText,
            cancelText,
            success: res => {
                if (res.confirm) {
                    resolve(true);
                } else {
                    reject(false);
                }
            },
            fail: res => reject(res)
        });
    });
};

export const isObject = (obj: any) => Object.prototype.toString.call(obj) === '[object Object]';

export const getLoginInfo = (callback: Function, index = 1) => {
	if (wx.getStorageSync('token')) {
		return callback && callback();
	}
	if (index > 100) return;
	setTimeout(() => {
		getLoginInfo(callback, index + 1);
	}, 100);
};

export const onLogined = async () => {
	return new Promise(resolve => {
		getLoginInfo(resolve);
	});
};